#include "openglcuttest.h"

OpenGLCutTest::OpenGLCutTest(QWindow *parent)
    : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent),
      time(nullptr), shaderProgram(nullptr), originPosX(nullptr), originPosY(nullptr),
      pointsAmount(0), color(0)
{
    qDebug() << "Type: OpenGL cut array test";
    count = 0;
    time = new QElapsedTimer();
    time->start();
    initializeOriginArraies(5000);
    setCutNum(50);
    this->setSurfaceType(QWindow::OpenGLSurface);
}

OpenGLCutTest::~OpenGLCutTest()
{
    delete time;
    delete shaderProgram;
    delete []originPosX;
    delete []originPosY;
}

void OpenGLCutTest::setCutNum(int num)
{
    cutNum = num;
    cutRound = pointsAmount / cutNum;
    cutLeft = cutRound % cutNum;
}

void OpenGLCutTest::initializeGL()
{
    initializeOpenGLFunctions();
    shaderProgram = new QOpenGLShaderProgram(this);
    shaderProgram->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shader/Shader/vShader.vsh");
    shaderProgram->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shader/Shader/fragShader.fsh");
    shaderProgram->link();
    shaderProgram->bind();
}

void OpenGLCutTest::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void OpenGLCutTest::paintGL()
{
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    f->glClearColor(0.0, 0.0, 0.0, 1.0);
    f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shaderProgram->bind();
    color = shaderProgram->uniformLocation("currentColor");
    lineColor = QVector4D(1.0, 1.0, 0.0, 1.0);
    shaderProgram->setUniformValue(color, lineColor);

    time->restart();
    xposAttri = shaderProgram->attributeLocation("xPos");
    yposAttri = shaderProgram->attributeLocation("yPos");
    GLfloat *xpos = new GLfloat[cutNum];
    GLfloat *ypos = new GLfloat[cutNum];
    qreal *tempOX = originPosX;
    qreal *tempOY = originPosY;
    GLfloat *tempX = xpos;
    GLfloat *tempY = ypos;
    int trap = pointsAmount - 1;
    shaderProgram->setAttributeArray(xposAttri, xpos, 1);
    shaderProgram->enableAttributeArray(xposAttri);
    shaderProgram->setAttributeArray(yposAttri, ypos, 1);
    shaderProgram->enableAttributeArray(yposAttri);

    for(int i = 0; i < cutRound; i++) {
        for(int k = 0; k < cutNum; k++) {
            *tempX = (GLfloat)(*tempOX) * 2 / trap - 1;
            *tempY = (*tempOY) * 0.8;
            tempX++; tempY++;
            tempOX++; tempOY++;
        }
        tempX = xpos;
        tempY = ypos;
        glDrawArrays(GL_LINE_STRIP, 0, cutNum);
    }
    delete []xpos; delete []ypos;
    xpos = new GLfloat[cutLeft];
    ypos = new GLfloat[cutLeft];
    tempX = xpos;
    tempY = ypos;
    for(int i = 0; i < cutLeft; i++) {
        *tempX = (GLfloat)(*tempOX) * 2 / trap - 1;
        *tempY = (*tempOY) * 0.8;
        tempX++; tempY++;
        tempOX++; tempOY++;
    }
    delete []xpos; delete []ypos;

    qDebug() << time->nsecsElapsed();
    count++;
    this->setTitle(QString::number(count));
}

void OpenGLCutTest::initializeOriginArraies(int num)
{
    pointsAmount = num;
    if(pointsAmount <= 0) {
        qDebug() << "Input Invalid";
        return;
    }
    else {
        time->restart();
        originPosX = new qreal[pointsAmount];
        originPosY = new qreal[pointsAmount];
        qreal *tempX = originPosX;
        qreal *tempY = originPosY;
        for(int i = 0; i < pointsAmount; i++) {
            *tempX = i;
            *tempY = qSin(M_PI / 500 * i);
            tempX++;
            tempY++;
        }
        qDebug() << "Init Time:" << time->nsecsElapsed() << "ns";

        for(int i = 0; i < 1000; i++) {
            qreal max;
            qreal min;
            tempY = originPosY;
            max = *tempX;
            min = *tempY;
            time->restart();
            for(int k = 1; k < pointsAmount; k++) {
                qreal temp = *tempY;
                if(temp > max) max = temp;
                if(temp < min) min = temp;
                temp++;
            }
            qDebug() << time->nsecsElapsed();
        }

        qDebug() << "paintGL:";
    }
}
